<!--
 * @Description: 
 * @Author: 胡涛
 * @Date: 2023-12-01 21:34:16
 * @LastEditors: 胡涛
 * @LastEditTime: 2024-07-18 22:32:44
-->
<template>
  <a-modal
    :open="visible"
    :keyboard="false"
    :maskClosable="false"
    :title="title"
    @cancel="onCancel"
    @ok="onSubmit"
    :confirmLoading="submitLoading"
    :width="900"
  >
    <a-form ref="formRef" v-bind="formLayout" :model="model" :rules="rules">
      <a-tabs class="tabs">
        <a-tab-pane key="info" tab="基本信息">
          <a-form-item label="所属分类" prop="categoryId">
            <a-tree-select
              v-model:value="model.categoryId"
              :treeData="categoryItems"
              :fieldNames ="{
                children: 'children',
                label: 'name',
                key: 'id',
                value: 'id',
              }"
            >
            </a-tree-select>
          </a-form-item>
          <a-form-item label="接口编码" prop="code">
            <a-input v-model:value="model.code"></a-input>
          </a-form-item>
          <a-form-item label="接口名称" prop="name">
            <a-input v-model:value="model.name"></a-input>
          </a-form-item>
          <a-form-item label="匿名访问" prop="allowAnonymous">
            <a-checkbox v-model:checked="model.allowAnonymous">
              {{ model.allowAnonymous ? "允许" : "不允许" }}
            </a-checkbox>
          </a-form-item>
          <a-form-item
            label="权限名称"
            prop="permissionName"
            v-if="!model.allowAnonymous"
          >
            <a-input v-model:value="model.permissionName"></a-input>
          </a-form-item>
          <a-form-item label="请求方式" prop="httpMethod">
            <enum-select
              name="HttpMethodEnum"
              v-model:value="model.httpMethod"
            />
          </a-form-item>
          <a-form-item label="启用状态" prop="status">
            <a-checkbox v-model:checked="model.status">启用/停用</a-checkbox>
          </a-form-item>
          <a-form-item label="备注" prop="remarks">
            <a-input v-model:value="model.remarks" />
          </a-form-item>
        </a-tab-pane>
        <a-tab-pane key="aaaa" tab="请求参数">
          <div class="grid">
            <a-row class="row row-header">
              <a-col class="cell" :span="6">参数名</a-col>
              <a-col class="cell" :span="9">参数说明</a-col>
              <a-col class="cell" :span="6">默认值</a-col>
              <a-col class="cell" :span="3">操作</a-col>
            </a-row>
            <a-row
              class="row"
              v-for="(item, index) in model.requestOptions"
              :key="index"
            >
              <a-col class="cell" :span="6">
                <a-input size="small" v-model:value="item.name" />
              </a-col>
              <a-col class="cell" :span="9"
                ><a-input size="small" v-model:value="item.description" />
              </a-col>
              <a-col class="cell" :span="6"
                ><a-input size="small" v-model:value="item.defaultValue" />
              </a-col>
              <a-col class="cell" :span="3">
                <a-button-group size="small">
                  <a-button
                    type="primary"
                    :disabled="index == 0"
                    @click="
                      model.requestOptions.splice(index, 1);
                      model.requestOptions.splice(index - 1, 0, item);
                    "
                    ><UpOutlined
                  /></a-button>
                  <a-button
                    type="primary"
                    :disabled="index == model.requestOptions.length - 1"
                    @click="
                      model.requestOptions.splice(index, 1);
                      model.requestOptions.splice(index + 1, 0, item);
                    "
                    ><DownOutlined
                  /></a-button>
                  <a-button
                    type="primary"
                    danger
                    @click="model.requestOptions.splice(index, 1)"
                    ><DeleteOutlined
                  /></a-button>
                </a-button-group>
              </a-col>
            </a-row>
          </div>
          <div class="bar">
            <a-button
              type="primary"
              @click="
                model.requestOptions.push({
                  name: '',
                  description: '',
                  defaultValue: '',
                })
              "
              >添加参数</a-button
            >
          </div>
        </a-tab-pane>
        <a-tab-pane key="attachments" tab="API接口脚本">
          <div class="script-editor" v-if="!extraLibLoading">
            <monaco-editor
              :height="500"
              language="javascript"
              :options="editorOptions"
              v-model:value="model.scriptContent"
              :extraLibSource="extraLibSource"
            ></monaco-editor>
          </div>
        </a-tab-pane>
      </a-tabs>
    </a-form>
  </a-modal>
</template>

<script lang="ts" setup>
import { useFormPage } from "@/helpers/pages";
import { FormInstance } from "ant-design-vue";
import { computed, onMounted, ref, watch } from "vue";
import libApi from "@/api";
import api from "@/api/report/httpApiConfig";
import { HttpApiConfigDto } from "@/api/report/types";
import {
  DeleteOutlined,
  UpOutlined,
  DownOutlined,
} from "@ant-design/icons-vue";
const formRef = ref<FormInstance>();
const emits = defineEmits(["update:visible", "close", "success"]);
const props = defineProps({
  id: String,
  visible: { type: Boolean, default: false },
  action: {
    type: String,
    default: "create",
  },
  item: {
    type: Object,
    default() {
      return {};
    },
  },
  categoryItems: { type: Array, required: true },
});
const formLayout2 = { labelCol: { span: 6 }, wrapperCol: { span: 16 } };

const editorOptions = {
  fontSize: 17,
};

const { model, rules, formLayout, loading, submitLoading } = useFormPage<
  HttpApiConfigDto,
  string
>({
  formLayout: { labelCol: { span: 3 }, wrapperCol: { span: 20 } },
  rules: {
    name: [{ required: true, message: "请输入接口名称信息" }],
    code: [{ required: true, message: "请输入接口编码信息" }],
    categoryId: [{ required: true, message: "请选择接口分类" }],
  },
  model: {
    name: "",
    code: "",
    categoryId: "",
    httpMethod: 1,
    permissionName: "",
    requestOptions: [],
    allowAnonymous: false,
    scriptContent: "",
    status: true,
    sortIndex: 0,
    remarks: "",
    demoSchema: "",
  },
});
const extraLibSource = ref<string>();
const extraLibLoading = ref(true);

const isEdit = computed(() => {
  return props.action === "edit";
});

/**
 * 弹窗标题
 */
const title = computed(() => {
  return isEdit.value ? "修改API接口信息" : "添加API接口信息";
});

const loadExtraLibSource = () => {
  libApi
    .get("./typescript/api.script.d.ts")
    .then((res) => {
      extraLibSource.value = res;
    })
    .finally(() => {
      extraLibLoading.value = false;
    });
  extraLibLoading.value = true;
};
/**
 * 加载数据
 */
const loadData = () => {
  if (isEdit.value) {
    loading.value = true;
    api.get(props.id).then((res) => {
      Object.assign(model, res);
      loading.value = false;
    });
  }
};

/**
 * 提交
 */
const onSubmit = () => {
  emits("success");
  formRef.value.validate().then(() => {
    let request = isEdit.value
      ? api.update(props.id, model)
      : api.create(model);
    submitLoading.value = true;
    request
      .then((res) => {
        emits("success", res);
        emits("update:visible", false);
        emits("close");
      })
      .finally(() => {
        submitLoading.value = false;
      });
  });
};

/**
 * 取消
 */
const onCancel = () => {
  emits("update:visible", false);
  emits("close");
};

watch(
  () => props.visible,
  (val: boolean) => {
    val && loadData();
  },
  { immediate: true }
);

onMounted(() => {
  loadExtraLibSource();
});
</script>

<style lang="less" scoped>
.tabs {
  margin-top: -12px;

  .grid {
    border: 1px solid #ddd;
    min-height: 360px;
  }
  .row {
    border-bottom: 1px solid #ddd;
    &-header {
      font-weight: bold;
      background: #eee;
    }
    &:last-child {
      border-bottom: 0 none;
    }
    .cell {
      padding: 5px;
    }
  }

  .bar {
    padding: 10px 0;
  }
}
</style>
